home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1993 / MacHack 1993.toast / MacHack™ 1987-1992 / MacHack™ '90 / Source Code ƒ / MPW C ƒ / BinhexCombiner / bhcomb.c next >
Encoding:
C/C++ Source or Header  |  1988-08-08  |  6.6 KB  |  240 lines  |  [TEXT/????]

  1. /*    bhcomb.c: combine and strip header information from BinHexed files.
  2.               for MacIntosh file transfer.
  3.     Author: R. J. Straka
  4.         (revised by G. A. Taylor)
  5.     Revision 1.1a
  6.     Date: July 6, 1987 (1.1a: March 31, 1988)
  7.  
  8.     Bhcomb is a program that takes a BinHexed MacIntosh file that
  9.     has been broken into several pieces to avoid electronic mailer
  10.     handling problems and splices them back together again.  Bhcomb
  11.     does this process in a totally automated fashion (when
  12.     accompanied by an appropriate shell script), and attempts to be
  13.     fairly rigorous by:
  14.  
  15.     1) Looking for the logical start of the file (delimited by the
  16.        string: "(This file ...)"
  17.     2) Checking each line of the input for proper length and validity
  18.        of all characters.
  19.     3) Looking for the logical end of the file.
  20.  
  21.     Bhcomb was developed under UNIX SVR2, and uses stdin, stdout
  22.        and stderr exclusively:
  23.         Stdin is used for the input.
  24.         Stdout is used for the valid file output.
  25.         Stderr is used for the garbage and diagnostics.
  26.  
  27.     After bhcombing, the user would typically use xmodem (or
  28.       similar) or macput on the resulting file.
  29.  
  30.     Bhcomb assumes the following BinHex file structure:
  31.  
  32.     several lines of unrelated header
  33.     (This file must be converted with BinHex 4.0)
  34.     :123456789012345678901234567890123456789012345678901234567890123
  35.     1234567890123456789012345678901234567890123456789012345678901234
  36.     .
  37.     .
  38.     .
  39.     1234567890123456789012345678901234567890123456789012345678901234
  40.     1234...4321:
  41.     several lines of unrelated footer
  42.  
  43.     Additional unrelated headers and/or footers may be present
  44.        within the data stream.
  45.     The actual data is prepended with "(This file... BinHex 4.0)"
  46.        and an extra blank line.
  47.     The actual data begins with a framing ":" (not checked)
  48.     The actual data must end with a framing ":"
  49.     All data lines (except potentially the last) are of the same
  50.        length (default=64).
  51.     The last data line is of random length, and ends with a ":".
  52.     Certain characters are never seen within the BinHex portion:
  53.         nothing < \012
  54.         nothing > \012, yet < \040
  55.         no spaces
  56.         no . / ; < = > ? O g n o s t u v w x y z { } characters
  57.         no | ~ \ ] ^ _ characters
  58.         nothing > \176
  59.  
  60.     Data is gathered through stdin.
  61.     Good data is sent to stdout.
  62.     Bad data and diagnostics are sent to stderr.
  63.  
  64.     A shell line (or procedure) of the following form is recommended:
  65.  
  66.        bhcomb <foo?.net >foo 2>foo.doc || echo ^G bhcomb Failed!
  67.  
  68.     Where the input filenames are foo1.net, foo2.net, ...  The shell
  69.        should put the files in the proper order given proper naming
  70.        convention by the files' creator.
  71.  
  72.     BUGS:
  73.         More than one BinHexed file per invocation ignores all
  74.           but the first BinHexed file.
  75.         Does not check for additional ":"s inside of the valid
  76.           portion of the data.
  77.         Has no way to check for files in inappropriate order
  78.           (except for the first and last)
  79.         Could be made more efficient by being table driven.
  80.         No manual page.  (You can tell I don't write
  81.           applications code for a living.)
  82.     
  83.     Revision Notes:
  84.         1.0:    Original Release
  85.         1.1:    Now recognizes last line of exactly LENGTH chars
  86.               without complaining.
  87.             Minor check added for out of sequence input files.
  88. */
  89.  
  90. #include <stdio.h>
  91. #include <string.h>
  92. #define    LENGTH    64            /* LENGTH = default BinHex line
  93.                          length = 64
  94.                     */
  95. char header[] = "(This file must be converted with BinHex 4.0)";
  96.  
  97. main(argc,argv)
  98. {
  99. int valid=0, started=0, lth;
  100.                     /* started = "we have started
  101.                          collecting valid BinHex data"
  102.                        valid = "the last line encountered
  103.                          was a valid BinHex line"
  104.                        lth = line length
  105.                     */
  106. char inline[256];
  107. while (gets (inline) >0)
  108.     {
  109.     /* Hacked to accept "StuffIt" encoding -- GAT 3/31/88 */
  110.     if (strncmp (inline,"(This file must be converted with BinHex 4.0)",45)==0
  111.      || strncmp (inline,"(Convert with BinHex or StuffIt)",32)==0)
  112.         {
  113.         if (started != 0)    /* Have we already started? */
  114.                     /* If so, something is wrong! */
  115.             {
  116.             started=0;    /* Unused hook for multiple files */
  117.             fprintf(stderr,"%s\n",inline);          /* Print it */
  118.             fprintf(stderr,"More than one BinHex file!\n");/*ERROR*/
  119.             exit (1);
  120.             }
  121.         else
  122.             {
  123.             /* Print "standard header" and blank line -- GAT 3/31/88 */
  124.             printf("%s\n",header);  /* "standard" header line */
  125.             printf("\n");        /* dummy blank line */
  126.             valid=1;        /* This line of data is valid */
  127.             started=1;        /* We started data gathering
  128.             */
  129.             }
  130.         }
  131.     else
  132.         {
  133.         lth=strlen (inline);
  134.  
  135.         if (lth == 0) /* Consume blank lines quietly  -- GAT 3/31/88 */
  136.             {
  137.             fprintf(stderr,"\n");
  138.             continue;
  139.             }
  140.  
  141.         if (badchars (inline,lth) != 0)    /* Do we have illegal chars? */
  142.             {
  143.             fprintf(stderr,"%s\n",inline);    /* Put to stderr */
  144.             valid=0;            /* Line not valid */
  145.             }
  146.         else
  147.             {                /* All chars OK */
  148.             if (strlen (inline) != LENGTH)    /* if bad line length */
  149.                 {
  150.                 if (valid!=1)    /*not expecting last line with :*/
  151.                     {
  152.                     fprintf(stderr,"%s\n",inline); /*bad line*/
  153.                     valid=0;    /* Line not valid */
  154.                     }
  155.                 else            /*expecting last line with : */
  156.                     {
  157.                     if (findcolon (inline) == 0)
  158.                     /* if colon at end of line */
  159.                         {
  160.                         printf("%s\n",inline); /* last line */
  161.                         started=2;    /* FINISHED */
  162.                         exit (0);    /* NORMAL EXIT */
  163.                         }
  164.                     else
  165.                         {
  166.                         fprintf(stderr,"%s\n",inline);
  167.                         valid=0;    /* bad line */
  168.                         }
  169.                     }
  170.                 }
  171.             else
  172.                 {
  173.                 if (started != 1)
  174.                     {
  175.                     fprintf(stderr,"%s\n",inline);    /* Print it */
  176.                     fprintf(stderr,"No beginning BinHex message; files may be out of order.\n");  /*ERROR*/
  177.                     fprintf(stderr,"Out of phase, get help. :-)\n");  /*ERROR*/
  178.                     exit (1);
  179.                     }
  180.                 else
  181.                     {
  182.                     printf("%s\n",inline);    /* Good line */
  183.                     valid=1;
  184.                     if (findcolon (inline) == 0)
  185.                     /* if colon at end of
  186.                        this 64 character line */
  187.                         {
  188.                         started=2;    /* FINISHED */
  189.                         exit (0);    /* NORMAL EXIT */
  190.                         }
  191.                     }
  192.                 }
  193.             }
  194.         }
  195.     }
  196. fprintf(stderr,"Improper EOF; no ending colon!\n");  /* should never get here */
  197. exit (2);
  198. }
  199.  
  200. badchars(lptr,length)            /* Look for illegal characters */
  201. char *lptr;
  202. int length;
  203. {
  204. int badchar, p;
  205. char c;
  206. c='a';
  207. badchar=0;
  208. for (p=0;p<length;p++)
  209.     {
  210.     c=lptr[p];
  211.     if (c < '\n')            {badchar=1; break;}
  212.     if (c > '\n' && c < '!') {badchar=1; break;}
  213.     if (c > '-' && c < 0)    {badchar=1; break;}
  214.     if (c > ':' && c < '@')  {badchar=1; break;}
  215.     if (c == 'O')            {badchar=1; break;}
  216.     if (c > '[' && c < '`')  {badchar=1; break;}
  217.     if (c == 'g')            {badchar=1; break;}
  218.     if (c > 'n' && c < 'o')  {badchar=1; break;}
  219.     if (c >  's')            {badchar=1; break;}
  220.     }
  221. return (badchar);
  222. }
  223.  
  224. findcolon(lptr)            /* Look for : at end of line */
  225. char *lptr;
  226. {
  227. int p;
  228. p=strlen(lptr);
  229. while (lptr[p--]=='\n') ;    /* get rid of all possible trailing \n_s */
  230. if (lptr[p]==':')
  231.     {
  232.     return (0);
  233.     }
  234. else
  235.     {
  236.     return (1);
  237.     }
  238. }
  239.  
  240.